use std::ffi::CStr;
use std::{
    ffi::{CString, c_char},
    io::{self, Read},
    thread,
    time::Duration,
};

extern "C" fn rust_string_log_callback(msg: *const c_char) {
    unsafe {
        if !msg.is_null() {
            let c_str = CStr::from_ptr(msg);
            if let Ok(str_slice) = c_str.to_str() {
                println!("[FFmpeg Log] {}", str_slice.trim_end());
            }
        }
    }
}

type RustLogStrCb = extern "C" fn(*const c_char);
unsafe extern "C" {
    fn ffmpeg_main(cmdline_str: *const c_char) -> i32; //, argc: i32, argv: *const *const c_char
    fn ffmpeg_stop();
    fn my_av_log_set_callback(cb: RustLogStrCb);
}

fn main() {
    unsafe {
        println!("🚀 启动 Rust + FFmpeg");

        my_av_log_set_callback(rust_string_log_callback);

        // 启动 FFmpeg 主线程
        let ffmpeg_thread = thread::spawn(|| {
            test_record10();
            println!("✅  test_record10(); 完成");
        });

        ffmpeg_thread.join().unwrap();
        println!("✅  test_record10() JOIN 完成");

        println!("✅ FFmpeg 完成,reader_thread");
    }
}

fn test_record10() {
    let args = vec![
        "ffmpeg",
        "-loglevel",
        "info",
        "-y",
        "-f",
        "gdigrab",
        "-i",
        "desktop",
        "-r",
        "10",
        "-t",
        "10",
        "-fs",
        "100M",
        "-b:v",
        "1M",
        // 关闭 [libx264 @ 000001EFA4792940] frame=  83 QP=11.62 NAL=0 Slice:B Poc:162 I:5    P:718  SKIP:15277 size=615 bytes
        // "-c:v", "libx264",
        //     "-x264-params", "log-level=1", // <- 不能拆开
        "test.mkv",
    ];

    let args = vec!["ffmpeg", "-version"];

    let args = vec![
        "ffmpeg",
        "-y",
        "-f",
        "gdigrab",
        "-i",
        "desktop",
        "-r",
        "10",
        "-t",
        "120",
        "-fs",
        "100M",
        "-b:v",
        "1M",
        "-vf",
        // 注意这个字符串必须是一个整体，否则 ffmpeg 会解析失败
        "scale=1024:-1,drawtext=fontfile=msyh.ttf:text='中文':fontsize=24:fontcolor=red:x=10:y=10,drawtext=fontfile=msyh.ttf:text='%{localtime}':x=mod(100*t\\,w):y=abs(sin(t))*h*0.7:box=0:fontcolor=red@0.5",
        "test1.mkv",
    ];

    // ffmpeg -y  -f gdigrab  -i desktop  -r 10  -t 120  -fs  100M  -b:v 1M  -vf "scale=1024:-1,drawtext=fontfile=msyh.ttf:text='中文':fontsize=24:fontcolor=red:x=10:y=10,drawtext=fontfile=msyh.ttf:text='%{localtime}':x=mod(100*t\,w):y=abs(sin(t))*h*0.7:box=0:fontcolor=red@0.5 " output.mp4
    let args = vec![
        "ffmpeg",
        "-y",
        "-probesize",
        "100M",
        // 桌面输入
        "-f",
        "gdigrab",
        "-r",
        "10",
        "-i",
        "desktop",
        // 摄像头输入
        "-f",
        "dshow",
        "-i",
        "video=\"FULL HD 1080P Webcam\"", // 注意这里不加引号
        // 滤镜合成：桌面缩放 + 摄像头缩放 + 叠加
        "-filter_complex",
        "[0]scale=1024:-1[desktop];[1]scale=160:120[cam];[desktop][cam]overlay=10:10",
        // 编码与输出设置
        "-b:v",
        "550k",
        "-c:v",
        "libx264",
        "test4.mkv",
    ];

    //let cstrings: Vec<CString> = args.iter().map(|s| CString::new(*s).unwrap()).collect();
    //let argv: Vec<*const c_char> = cstrings.iter().map(|cs| cs.as_ptr()).collect();
    let cmdline_str = CString::new(args.join(" ")).unwrap();

    // 停止 FFmpeg
    let stopper = thread::spawn(|| {
        let duration = 30;
        thread::sleep(Duration::from_secs(duration));
        println!("🛑 {} 秒到了，调用 ffmpeg_stop()", duration);
        unsafe {
            ffmpeg_stop();
        }
    });

    unsafe {
        ffmpeg_main(cmdline_str.as_ptr()); //, argv.len() as i32, argv.as_ptr()
    }
    //123456789
    stopper.join().unwrap();
}
